package org.jeecg.modules.utils;

import org.apache.shiro.codec.Hex;
import org.jeecg.modules.param.member.entity.BikeMemberUserCard;
import org.jeecg.modules.utils.est100.JavaCallCppService;
import org.springframework.stereotype.Component;
/**
 *
 * 读卡器 读写 工具包
 * */

@Component
public class EstUtils {
	/**
	 * 获取的 hex+crc8 编号 编译为 Ascii String
	 * */
	public static String hexAddCrc8ToAscii(String str){
		String substring = str.substring(0, 30);
		return hexToAscii(substring);
	}
	/**
	 * 车辆编号转16 加crc8验证 存后两位 共32位 其余补0
	 * */
	public static String asciiToHexAddCrc8(String str){
		int strLength = 32;
		StringBuilder hex = new StringBuilder(asciiToHex(str));
		String a = "0";
		String CRC8 =  CRC8_MAXIM(str.getBytes(), 0, str.getBytes().length);
		for (int i = hex.length(); i < strLength-1; i++) {
			if (i!=30){
				hex.append(a);
			}else {
				hex.append(CRC8);
			}
		}
		String s = hex.toString();
		return s;
	}

	/*获取16进制String的CRC8 MAXIM校验码*/
	public static String CRC8_MAXIM(byte[] source, int offset, int length) {
		int wCRCin = 0x00;
		// Integer.reverse(0x31) >>> 24
		int wCPoly = 0x8C;
		for (int i = offset, cnt = offset + length; i < cnt; i++) {
			wCRCin ^= ((long) source[i] & 0xFF);
			for (int j = 0; j < 8; j++) {
				if ((wCRCin & 0x01) != 0) {
					wCRCin >>= 1;
					wCRCin ^= wCPoly;
				} else {
					wCRCin >>= 1;
				}
			}
		}
		wCRCin ^= 0x00;
		String s = Integer.toHexString(wCRCin);
		if(wCRCin < 16){
			return "0" + s;
		} else {
			return s;
		}
	}

	/*获取16进制String的CRC8 MAXIM校验码*/
	public static boolean checkBikeErr(byte[] source, int offset, int length) {
		int wCRCin = 0x00;
		// Integer.reverse(0x31) >>> 24
		int wCPoly = 0x8C;
		for (int i = offset, cnt = offset + length; i < cnt; i++) {
			wCRCin ^= ((long) source[i] & 0xFF);
			for (int j = 0; j < 8; j++) {
				if ((wCRCin & 0x01) != 0) {
					wCRCin >>= 1;
					wCRCin ^= wCPoly;
				} else {
					wCRCin >>= 1;
				}
			}
		}
		wCRCin ^= 0x00;
		String s = Integer.toHexString(wCRCin);
		if (s.equals("0")){
			return true;
		}
		if(wCRCin < 16){
			return false;
		}else {
			return true;
		}
	}
    /*hex 进制转 ascii*/
	public static String hexToAscii(String hexStr) {
		StringBuilder output = new StringBuilder("");
		for (int i = 0; i < hexStr.length(); i += 2) {
			String str = hexStr.substring(i, i + 2);
			output.append((char) Integer.parseInt(str, 16));
		}
		String s = output.toString();
		s = s.replace("\u0000", "");
		return s;
	}
	/*ascii转hex*/
	public static String asciiToHex(String asciiStr) {
		char[] chars = asciiStr.toCharArray();
		StringBuilder hex = new StringBuilder();
		for (char ch : chars) {
			hex.append(Integer.toHexString((int) ch));
		}
		return hex.toString();
	}

    /**
     * 读取卡
	 * 返回code
	 *
     * */
    public static String getCarCode(){
		byte[] anticollUid = new byte[10];
		byte tpye = 0x41; //0x41表示TypeA/M1，0x42表示TypeB
		byte mode=0x60; //认证KeyA = 0x60， KeyB=0x61
		//code 在 2号扇区
	    byte secNr=2;;//此处填写实际的扇区 0~15
	    byte[] passWord = {(byte)0xff,(byte) 0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
	    byte[] data = new byte[50];
	    //9号区块为 code
    	byte addr=9;//此处填写实际的块 0~63

    	int hReader = JavaCallCppService.INSTANCE.EU_Reader_Open("USB1");
    	 if(hReader <= 0){
    		 System.err.println("==打开接口失败,状态码:"+hReader);
    		 return null;
    	 }
    	 //请求卡片
    	 int request = JavaCallCppService.INSTANCE.PEU_Reader_Request(hReader);
    	 if(request != 0){
    		 System.err.println("==请求卡片接口失败==request=="+request+"=======状态码====="+request);
    		 return null;
    	 }
    	 //防碰撞
    	int anticoll = JavaCallCppService.INSTANCE.PEU_Reader_anticoll(hReader,anticollUid);
    	if(anticoll != 0){//结果等于0 表示成功
    		System.out.println("==防碰撞接口失败==anticoll=="+anticoll+"=======状态码====="+anticoll);
    		return null;
    	}
    	//选择卡片
	    int select = JavaCallCppService.INSTANCE.PEU_Reader_Select(hReader,tpye);
	    System.out.println(" select="+select);
	    if(select!=0){//结果等于0表示成功
	    	System.out.println("==选择接口失败==request=="+select+"=======状态码====="+select);
	    	return null;
	    }
        //M1卡认证密钥，该函数将使用参数PassWord传入的Key进行认证 //认证KeyA = 0x60
	    int auPass = JavaCallCppService.INSTANCE.PEU_Reader_Authentication_Pass(hReader,mode,secNr,passWord);
	    if(auPass!=0){
	    	System.out.println("==验证接口失败==auPass=="+auPass+"=======状态码====="+auPass);
	    	return null;
	    }
	    //读取M1卡片块数据
    	int reader = JavaCallCppService.INSTANCE.PEU_Reader_Read(hReader,addr,data);
    	if(reader!=0){
    		System.out.println("==读卡接口失败==reader=="+reader+"=======状态码====="+reader);
    		return null;
    	}
		String s = new String(data);
		//存入十进制code值
		return s.substring(0,16);

    }
	/**
	 * 初始化卡Code
	 * 返回 新 code
	 * todo 算法没存
	 * */
	public static String setCarCode(){
		byte[] anticollUid = new byte[10];
		byte tpye = 0x41; //0x41表示TypeA/M1，0x42表示TypeB
		byte mode=0x60; //认证KeyA = 0x60， KeyB=0x61
		//code 在 2号扇区
		byte secNr=2;;//此处填写实际的扇区 0~15
		byte[] passWord = {(byte)0xff,(byte) 0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
		String ic = RandomCodeUtils.getIcCode("IC");
		byte[] data = ic.getBytes();
		//9号区块为 code
		byte addr=9;//此处填写实际的块 0~63



		int hReader = JavaCallCppService.INSTANCE.EU_Reader_Open("USB1");

		if(hReader <= 0){
			System.err.println("==打开接口失败,状态码:"+hReader);
			return null;
		}
		//请求卡片
		int request = JavaCallCppService.INSTANCE.PEU_Reader_Request(hReader);

		if(request != 0){
			System.err.println("==请求卡片接口失败==request=="+request+"=======状态码====="+request);
			return null;
		}
		//防碰撞
		int anticoll = JavaCallCppService.INSTANCE.PEU_Reader_anticoll(hReader,anticollUid);

		if(anticoll != 0){//结果等于0 表示成功
			System.out.println("==防碰撞接口失败==anticoll=="+anticoll+"=======状态码====="+anticoll);
			return null;
		}
		//选择卡片
		int select = JavaCallCppService.INSTANCE.PEU_Reader_Select(hReader, tpye);

		if (select != 0) {//结果等于0表示成功
			System.out.println("==选择接口失败==request==" + select + "=======状态码=====" + select);
			return null;
		}
		//M1卡认证密钥，该函数将使用参数PassWord传入的Key进行认证 //认证KeyA = 0x60
		int auPass = JavaCallCppService.INSTANCE.PEU_Reader_Authentication_Pass(hReader, mode, secNr, passWord);

		if (auPass != 0) {
			System.out.println("==验证接口失败==auPass==" + auPass + "=======状态码=====" + auPass);
			return null;
		}

		int write = JavaCallCppService.INSTANCE.PEU_Reader_Write(hReader, addr, data);
		if (write != 0) {
			System.out.println("==写卡接口失败==reader==" + write + "=======状态码=====" + write);
			return null;
		}
		String s = new String(data);
		return s.substring(0,16);
	}




	///**
	// * 打印字节数组
	// * */
	//public static void print_byteArray(byte[] src, int length) {
	//	for (int i = 0; i < length; ++i) {
	//		String hex = Integer.toHexString(src[i] & 0xFF);
	//		if (hex.length() == 1) {
	//            hex = '0' + hex;
	//        }
	//		System.out.print(hex);
	//    }
	//
	//}
}
